﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using Model.LiveControl;
using Network;
using Network.Messages.FileTranser;
using Providers.FileTransfer.Client;

namespace Managers.FileTransfer.Client
{
   public sealed class FileTransferCilentManager : Manager<FileTransferClientProvider>
    {
       public FileTransferCilentManager(NetworkPeer network) : base(new FileTransferClientProvider(network))
       {
            Provider.ServerCopyChanged += Provider_ServerCopyChanged;

            Provider.OnCopyfileRecived += Provider_OnCopyfileRecived;

            Provider.OnNotifyNewTextCanPaste += Provider_OnNotifyNewTextCanPaste;
       }

        private void Provider_OnNotifyNewTextCanPaste(object sender, NotifyNewTextCanPasteMessage e)
        {
            SetCopyText(e.Text);
        }

        private void SetCopyText(string text)
        {
            try
            {
                if (Clipboard.ContainsText())
                {
                    var cbText = Clipboard.GetText();
                    if (cbText == text)
                    {
                        return;
                    }
                }

                Clipboard.SetText(text);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                //throw;
            }
          
           

        }


        private void Provider_OnCopyfileRecived(object sender, ResponseEndCopyFileMessage e)
        {
            OnCopyfileRecived?.Invoke(sender,e);
        }

        public event EventHandler<ResponseEndCopyFileMessage> OnCopyfileRecived;

        private void Provider_ServerCopyChanged(object sender, NotifyNewFileCanCopyMessge e)
        {
            SetCopyDate(e.FlieItemList);
            ServerCopyChanged?.Invoke(sender, e);
        }
        private void SetCopyDate(List<FileItem> fileItemList)
        {
            
            var folders = fileItemList.Where(p => p.IsFolder);
            var files = fileItemList.Where(p => !p.IsFolder).ToArray();
            
            DataObjectEx.SelectedItem[] selectedItems = new DataObjectEx.SelectedItem[files.Length];

            //foreach (var fileItem in folders)
            //{
            //    Directory.CreateDirectory(fileItem.FileName);
            //}

            int fileIndex = 0;
            foreach (var fileItem in files)
            {
                selectedItems[fileIndex].FileName = fileItem.FileName;
                selectedItems[fileIndex].SourceFileName = fileItem.SourceFileName;
                selectedItems[fileIndex].WriteTime = fileItem.WriteTime;
                selectedItems[fileIndex].FileSize = fileItem.FileSize;
                selectedItems[fileIndex].IsFolder = fileItem.IsFolder;
                selectedItems[fileIndex].Contents = Contents;
                fileIndex++;
            }
            DataObjectEx dataObject = new DataObjectEx(selectedItems);


            dataObject.SetData(NativeMethodsCopyClipboard.CFSTR_FILEDESCRIPTORW, null);
            dataObject.SetData(NativeMethodsCopyClipboard.CFSTR_FILECONTENTS, null);
            dataObject.SetData(NativeMethodsCopyClipboard.CFSTR_PERFORMEDDROPEFFECT, null);
            Clipboard.SetDataObject(dataObject);
        }

        private async Task<string> Contents(DataObjectEx.SelectedItem selectedItem)
        {
            var result = await RequestPasteAsTask(selectedItem);
            return result.DestFile;
        }

        /// <summary>
        /// 请求粘贴事件响应
        /// </summary>
        /// <param name="selectedItem"></param>
        /// <returns></returns>
        public Task<ResponseEndCopyFileMessage> RequestPasteAsTask(DataObjectEx.SelectedItem selectedItem)
        {
            var tcs = RegisterAsTask(ref OnCopyfileRecived,selectedItem);

            var childTask = Task.Factory.StartNew(() =>
            {
                string temp = AppDomain.CurrentDomain.BaseDirectory+"Temp";
                Provider.NotifyStartServerPasteAFile(temp, selectedItem.SourceFileName);
            }, TaskCreationOptions.AttachedToParent);
            
            return tcs.Task;
        }
        /// <summary>
        /// 注册一个任务，该任务的任务周期为等待事件触发及事件上当前挂载的所有委托的函数执行完成全过程。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="eventMethod"></param>
        /// <returns></returns>
        public TaskCompletionSource<ResponseEndCopyFileMessage> RegisterAsTask(ref EventHandler<ResponseEndCopyFileMessage> eventMethod, DataObjectEx.SelectedItem selectedItem)
        {
            TaskCompletionSource<ResponseEndCopyFileMessage> tcs = null;
            try
            {
                // Create a new TaskCompletionSource to represent the finished event 
                tcs = new TaskCompletionSource<ResponseEndCopyFileMessage>();

                // Add a custom handler for this event that completes TaskCompletionSource
                EventHandler<ResponseEndCopyFileMessage> eventHandler = null;

                //如果设置成功，会触发task的OnCompleted事件，也就会走await后面的代码。
                eventHandler = (s, e) =>
                {
                    if (selectedItem.SourceFileName == e.SourceFile)
                    {
                        tcs.TrySetResult(e);
                    }
                };
                eventMethod += eventHandler;

                // Remove all completed event handlers
                Delegate[] delegates = eventMethod.GetInvocationList();

                if (delegates.Length > 1)
                {
                    for (int i = 0; i < delegates.Length; i++)
                    {
                        try
                        {
                            dynamic dynamicDelegateTarget = delegates[i].Target;
                            if (dynamicDelegateTarget.tcs.Task.Status == TaskStatus.RanToCompletion)
                            {
                                eventMethod -= (EventHandler<ResponseEndCopyFileMessage>)delegates[i];
                            }
                        }
                        catch
                        {
                        }
                    }
                }
            }
            catch { }

            // Return the uncompleted TaskCompletionSource; using async, the completed TaskCompletionSource will be returned after T event fires
            return tcs;
        }
        #region 对外接口



        /// <summary>
        /// 启动远程粘贴
        /// </summary>
        public void NotifyStartSeverPaste(string dir)
        {
           Provider.NotifyStartSeverPaste(dir);
        }

        /// <summary>
        /// 执行了本地复制，移除远程复制状态
        /// </summary>
        public void NativeCopyFired()
        {
            Provider.NativeCopyFired();
        }

        /// <summary>
        /// 服务端发生了新的复制
        /// </summary>
        public event EventHandler<NotifyNewFileCanCopyMessge> ServerCopyChanged;

        #endregion
    }
}
